package databaseComm;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import results.IncorrectProblemStatistic;
import results.Result;
import accounts.Account;
import accounts.Admin;
import accounts.Instructor;
import accounts.Student;
import equations.AdditionStub;
import equations.DivisionStub;
import equations.FractionToDecimalStub;
import equations.MathFactsCategory;
import equations.Multiplication1Stub;
import equations.Multiplication2Stub;
import equations.Problem;
import equations.SubtractionStub;

/**
 * This is the stubbed database API
 * @author stewarte
 *
 */
public class DatabaseAccessAPIStub implements DatabaseDriverInterface{
	
	public DatabaseAccessAPIStub(String address){
		connectToDatabase(address);
	}
	
	@Override
	public  boolean connectToDatabase(String address) {
		//TODO: Implement connect code
		return true;
	}

	@Override
	public Account authenticateLogin(String username, String password) {
		//these are the stubbed accounts
		Account retVal=null;
		
		//TODO: instead of this code, we query the database for a given username and password, it should return
		// username, password, first name, last name, and account type, then construct retval appropriately and return it.
		
		//we should base this if block based on the account type.
		if(username.equals("instructor")){
			retVal = new Instructor("instructor",password,"Emil","Stewart");
		}else if(username.equals("student")){
			retVal = new Student("student",password,"Mike","Williams");
		}else if(username.equals("admin")){
			retVal = new Admin("admin", password, "Akram", "Khan");
		}
		return retVal;
	}

	@Override
	public boolean createAccount(Account creator, Account toBeCreated) {
		
		//only create an account if we are an admin
		if(creator instanceof Admin){
			//TODO:We would dissect the account to be created and add it to the database appropriately.
			//to do this, we get the instance of the toBeCreated object, this tells us the account type
			//then we get the username, password, and first and last name information from toBeCreated
			//and add it as a row to the database
			return true;
		}
		return false;
	}


	@Override
	public String retrievePassword(Account retriever, String username) {
		//TODO:query the database based on the username and get the password
		return "password";
	}

	@Override
	public boolean addResult(Result r) {
		//TODO: Add the result to the database, result has 
		//countIncorrect,totalquestions,username,mathfactscategory,and date
		//use these to fill in a row in the table.
		return true;
	}

	@Override
	public List<Result> getAllResultsForCategory(MathFactsCategory mfc,
			String username) {
		List<Result> results = new ArrayList<Result>();
		
		//use this category name to search the database category
		String categoryname = mfc.toString();
		
		//TODO: create a result for each row returned for a categoryname and username
		
		//now that we have the query, create individual results and add them to the
		//list of results, iterate through the query adding results every time
		
		Result r = new Result(14,20,username,mfc,new Date());
		results.add(r);
		
		r = new Result(35,40,username,mfc,new Date());
		results.add(r);
		r = new Result(90,100,username,mfc,new Date());
		results.add(r);
		
		return results;
	}


	@Override
	public boolean addIncorrectEquationResult(Problem p, String username) {
		// TODO Check to see if the problem is already in the database of incorrect problems for a given username
		// if it is, then simply increment the count for that problem. If it isn't
		// then add a new row with the given equation and username and a count of 1
		
		//obviously return false if unsuccessfull, true if successful
		return true;
	}

	@Override
	public List<IncorrectProblemStatistic> getIncorrectProblemsStatistics(
			String username) {
		
		List<IncorrectProblemStatistic> probStats = new ArrayList<IncorrectProblemStatistic>();
		// TODO Query the table of incorrect problems, populate the returned rows
		//into "IncorrectProblemStatistic" objects, and add them to an arraylist
		//of IncorrectProblemStatistics. 
		
		Problem p = new Problem("3 X 8 =", "24");
		IncorrectProblemStatistic ips = new IncorrectProblemStatistic(p,2);
		probStats.add(ips);
		
		p = new Problem("3 X 3 =", "9");
		ips = new IncorrectProblemStatistic(p,2);
		probStats.add(ips);
		
		p = new Problem("3 X 4 =", "12");
		ips = new IncorrectProblemStatistic(p,2);
		probStats.add(ips);
		
		p = new Problem("3 X 9 =", "27");
		ips = new IncorrectProblemStatistic(p,2);
		probStats.add(ips);
		
		return null;
	}

	@Override
	public boolean usernameAvailable(String username) {
		// TODO: Query the database to see if the username is in the database already
		return true;
	}

	@Override
	public boolean deleteAccount(Account deleter, String username) {
		
		boolean exists = this.usernameAvailable(username);
		
		
		if(deleter instanceof Admin && exists ){
			
			//TODO: Delete the account from the database if it exists
			
			return true;
		}else{
			return false;
		}
	}

	@Override
	public boolean changePassword(Account changer, String username,
			String newPassword) {
		//only change password if username is available, the changer is an instructor or admin
		if(this.usernameAvailable(username) && (changer instanceof Instructor || changer instanceof Admin)){
			//TODO: Implement change password query, change the password of the username, to newPassword
			return true;
		}
		return false;
	}

	@Override
	public List<Result> getAllResults(String username) {
		
		List<Result> results = new ArrayList<Result>();
		
		//TODO: Replace these stubs with actual results taken from the database.
		// you will have to initialize real math facts categories every time you create
		//a new result. You can get the category type, the username, incorrect scores, total, 
		//and date from the database. Add these results to the list and return the list.
		Result r = new Result(14,20,username,new Multiplication1Stub(),new Date());
		results.add(r);
		
		r = new Result(35,40,username,new Multiplication2Stub(),new Date());
		results.add(r);
		
		r = new Result(90,100,username,new DivisionStub(),new Date());
		results.add(r);
		
		return results;
		
	}

	
	@Override
	public MathFactsCategory getAllEquationsForCategory(String categoryname) {
		//Initialize a mathfacts category as taken from the database 
		MathFactsCategory mfc1 = new AdditionStub();
		MathFactsCategory mfc2 = new Multiplication1Stub();
		MathFactsCategory mfc3 = new Multiplication2Stub();
		MathFactsCategory mfc4 = new DivisionStub();
		MathFactsCategory mfc5 = new SubtractionStub();
		MathFactsCategory mfc6 = new FractionToDecimalStub();
		
		if(categoryname.equals(mfc1.toString())){
			return mfc1;
		}else if(categoryname.equals(mfc2.toString())){
			return mfc2;
		} else if(categoryname.equals(mfc3.toString())){
			return mfc3;
		} else if(categoryname.equals(mfc4.toString())){
			return mfc4;
		} else if(categoryname.equals(mfc5.toString())){
			return mfc5;
		} else if(categoryname.equals(mfc6.toString())){
			return mfc6;
		} 
		
		return null;
	}

}
